]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
appDisplay: Add placeholder when moving from folder dialog
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>
Tue, 23 Jun 2020 15:05:27 +0000 (12:05 -0300)
committerFlorian Müllner <florian.muellner@gmail.com>
Mon, 20 Jul 2020 16:13:20 +0000 (16:13 +0000)
When moving an icon from a folder dialog, the app grid doesn't
really have an icon to move around.

Add a placeholder icon and hijack it in the various places.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284

js/ui/appDisplay.js

index 5eff0c3b96352f9931958aaf92c6ee1ef10c147d..eb9f228cacad7e53de5c6706b9e1207f03bb3c51 100644 (file)
@@ -668,6 +668,7 @@ class AppDisplay extends BaseAppView {
         this._lastOvershootTimeoutId = 0;
         this._delayedMoveId = 0;
         this._targetDropPosition = null;
+        this._placeholder = null;
 
         Main.overview.connect('hidden', () => this.goToPage(0));
 
@@ -755,17 +756,44 @@ class AppDisplay extends BaseAppView {
         this._pageManager.pages = pages;
     }
 
+    _ensurePlaceholder(source) {
+        if (this._placeholder)
+            return;
+
+        const appSys = Shell.AppSystem.get_default();
+        const app = appSys.lookup_app(source.id);
+
+        const isDraggable =
+            global.settings.is_writable('favorite-apps') ||
+            global.settings.is_writable('app-picker-layout');
+
+        this._placeholder = new AppIcon(app, { isDraggable });
+        this._placeholder.scaleAndFade();
+        this._redisplay();
+    }
+
+    _removePlaceholder() {
+        if (this._placeholder) {
+            this._placeholder.undoScaleAndFade();
+            this._placeholder = null;
+            this._redisplay();
+        }
+    }
+
     getAppInfos() {
         return this._appInfoList;
     }
 
     _getItemPosition(item) {
+        if (item === this._placeholder)
+            return this._grid.getItemPosition(item);
+
         return this._pageManager.getAppPosition(item.id);
     }
 
     _compareItems(a, b) {
-        const [aPage, aPosition] = this._pageManager.getAppPosition(a.id);
-        const [bPage, bPosition] = this._pageManager.getAppPosition(b.id);
+        const [aPage, aPosition] = this._getItemPosition(a);
+        const [bPage, bPosition] = this._getItemPosition(b);
 
         if (aPage === -1 && bPage === -1)
             return a.name.localeCompare(b.name);
@@ -843,6 +871,10 @@ class AppDisplay extends BaseAppView {
             appIcons.push(icon);
         });
 
+        // At last, if there's a placeholder available, add it
+        if (this._placeholder)
+            appIcons.push(this._placeholder);
+
         return appIcons;
     }
 
@@ -955,7 +987,7 @@ class AppDisplay extends BaseAppView {
         if (!success)
             return;
 
-        const { source } = dragEvent;
+        const source = this._placeholder ? this._placeholder : dragEvent.source;
         const [page, position, dragLocation] =
             this._getDropTarget(x, y, source);
         const item = position !== -1
@@ -1041,11 +1073,18 @@ class AppDisplay extends BaseAppView {
             '[gnome-shell] this._lastOvershootTimeoutId');
     }
 
-    _onDragBegin() {
+    _onDragBegin(_overview, source) {
         this._dragMonitor = {
             dragMotion: this._onDragMotion.bind(this),
         };
         DND.addDragMonitor(this._dragMonitor);
+
+        // When dragging from a folder dialog, the dragged app icon doesn't
+        // exist in AppDisplay. We work around that by adding a placeholder
+        // icon that is either destroyed on cancel, or becomes the effective
+        // new icon when dropped.
+        if (_getViewFromIcon(source) instanceof FolderView)
+            this._ensurePlaceholder(source);
     }
 
     _onDragMotion(dragEvent) {
@@ -1072,6 +1111,7 @@ class AppDisplay extends BaseAppView {
         }
 
         this._resetOvershoot();
+        this._removePlaceholder();
     }
 
     _onDragCancelled(_overview, source) {